<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
<script>
  class MaxConcurrency {
  constructor(maxConcurrency) {
    this.maxConcurrency = maxConcurrency;
    this.currentTaskCount = 0;
    this.tasks = [];
  }
  get(url) {
    // 分析得知，get 返回 promise
    // 当并发数还没到的时候，直接返回promise
    // 如果并发数满了，将任务放进队列里面
    if (this.currentTaskCount < this.maxConcurrency) {
      this.currentTaskCount++;
      return new Promise((resolve, reject) => {
        fetch(url)
          .then((res) => {
            resolve(res);
          })
          .catch((e) => {
            reject(e);
          })
          .finally(() => {
            this.currentTaskCount--;
            const task = this.tasks.shift();
            if (task) {
              task();
            }
          });
      });
    }
    return new Promise((resolve, reject) => {
      this.tasks.push(() => {
        fetch(url)
          .then((res) => {
            resolve(res);
          })
          .catch((e) => {
            reject(e);
          })
          .finally(() => {
            this.currentTaskCount--;
            const task = this.tasks.shift();
            if (task) {
              task();
            }
          });
      });
    });
  }
}

const rq = new MaxConcurrency(2);

const p1 = rq.get('http://127.0.0.1:3000/');
const p2 = rq.get('http://127.0.0.1:3000/');
const p3 = rq.get('http://127.0.0.1:3000/');

Promise.all([p1, p2, p3]);
</script>
</html>